package com.bf.electroplating.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bf.electroplating.login.UserContext;
import com.bf.electroplating.login.UserDetail;
import com.bf.electroplating.pojo.dto.LoginDTO;
import com.bf.electroplating.pojo.dto.ChangePasswordDTO;
import com.bf.electroplating.pojo.entity.*;
import com.bf.electroplating.pojo.enums.AttModuleEnums;
import com.bf.electroplating.pojo.enums.FunctionEnums;
import com.bf.electroplating.pojo.vo.ResultVO;
import com.bf.electroplating.pojo.vo.SelectVo;
import com.bf.electroplating.service.*;
import com.bf.electroplating.util.DESUtil;
import com.bf.electroplating.util.JwtUtils;
import com.bf.electroplating.util.MD5Util;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author ping
 */
@RestController
@RequestMapping("/after")
@Tag(name = "后台登录", description = "后台登录")
@Slf4j
public class LoginAfterController {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private ISysUserRoleService sysUserRoleService;
    @Resource
    private ISysRoleFunctionService sysRoleFunctionService;
    @Resource
    private ISysFunctionService sysFunctionService;
    @Resource
    private ComCompanyService companyService;
    @Resource
    private PubParamDictionaryService pubParamService;
    @Resource
    private PubAttachmentService pubAttachmentService;


    private final String SALT="biekanwozhishiyizhiyang";

    @PostMapping("/login")
    @Operation(summary = "登录", description = "登录")
    public ResultVO<Object> login(@RequestBody LoginDTO dto) {
        if (dto.getUserAccountName() == null || dto.getPassword() == null) {
            return ResultVO.fail("用户名或密码不能为空");
        }
        SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserAccountName, dto.getUserAccountName()));
        if (sysUser == null) {
            return ResultVO.fail("账号不存在，请重新输入！");
        }
        List<ComCompany> company = companyService.list();
        Map<String, String> companyMap = company.stream().collect(Collectors.toMap(ComCompany::getId, ComCompany::getCompanyName));
        List<SelectVo> park = pubParamService.getParamList("PARK").getData();
        Map<String, String> parkMap = park.stream().collect(Collectors.toMap(SelectVo::getId, SelectVo::getName));
        try {
            String des = DESUtil.decryptByDES(dto.getPassword());
            if (MD5Util.MD5Encode(MD5Util.MD5Encode(des+SALT)).equals((sysUser.getPassword()))) {
                String token = JwtUtils.generateToken(dto.getUserAccountName());
                UserDetail userInfo=new UserDetail();
                BeanUtils.copyProperties(sysUser, userInfo);
                userInfo.setCompanyName(companyMap.get(userInfo.getCompanyId()));
                userInfo.setParkName(parkMap.get(userInfo.getParkId()));
                List<SysUserRole> sysUserRoles = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUId, userInfo.getId()));
                userInfo.setRoleIds(sysUserRoles.stream().map(SysUserRole::getRId).collect(Collectors.toList()));
                Set<String> functionIds = new HashSet<>();
                for (String roleId : userInfo.getRoleIds()) {
                    functionIds.addAll(sysRoleFunctionService.list(new LambdaQueryWrapper<SysRoleFunction>().eq(SysRoleFunction::getRId, roleId)).stream().map(SysRoleFunction::getFId).collect(Collectors.toList()));
                }
                if (!functionIds.isEmpty()){
                    userInfo.setFunctionIds(new ArrayList<>(functionIds));
                    List<String> parkIds = sysFunctionService.list(new LambdaQueryWrapper<SysFunction>()
                            .in(SysFunction::getId, functionIds)
                            .eq(SysFunction::getRemarks, "park")).stream().map(SysFunction::getFunctionCode).toList();
                    userInfo.setParkFunctionIds(parkIds);
                }
                ComCompany comcompany = companyService.getById(userInfo.getCompanyId());
                if (company!=null){
                    userInfo.setBelongSewageCode(comcompany.getBelongSewageCode());
                }
                userInfo.setAttachmentVo(pubAttachmentService.getOneFile(userInfo.getId(), AttModuleEnums.USER_PHOTO.getCode()));
                // 将用户详细信息保存到 Redis
                saveUser(token, userInfo);
                return ResultVO.ok(token, "登录成功");
            } else {
                return ResultVO.fail("密码错误");
            }
        } catch (Exception e) {
            log.error("登录异常："+e);
            throw new RuntimeException(e);
        }
    }

    @GetMapping("/getUser")
    @Operation(summary = "获取用户信息", description = "获取用户信息")
    public ResultVO<UserDetail> getUserInfo() {
        UserDetail userInfo = UserContext.getUser();
        if (userInfo.getRoleIds().contains(FunctionEnums.CRUD.getCode())){
            userInfo.setIsOperate("1");
        }else {
            userInfo.setIsOperate("0");
        }
        return ResultVO.ok(userInfo);
    }

    private final static String TOKEN_PREFIX = "user:";

    @PostMapping("/changePassword")
    @Operation(summary = "修改密码", description = "修改用户密码")
    public ResultVO<Object> changePassword(@RequestBody ChangePasswordDTO dto) {
        try {
            // 参数验证
            if ( dto.getNewPassword() == null) {
                return ResultVO.fail("新密码不能为空");
            }
            
            if (dto.getNewPassword().trim().isEmpty()) {
                return ResultVO.fail("新密码不能为空");
            }
            
            // 从UserContext获取当前用户信息
            UserDetail currentUser = UserContext.getUser();
            if (currentUser == null) {
                return ResultVO.fail("用户未登录");
            }

            // 根据用户账号名查询用户信息
            SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getUserAccountName, currentUser.getUserAccountName()));

            if (sysUser == null) {
                return ResultVO.fail("用户不存在");
            }
            

            // 加密新密码
            String desNewPassword = DESUtil.decryptByDES(dto.getNewPassword());
            String encryptedNewPassword = MD5Util.MD5Encode(MD5Util.MD5Encode(desNewPassword + SALT));
            
            // 更新密码
            sysUser.setPassword(encryptedNewPassword);
            boolean updateResult = sysUserService.updateById(sysUser);
            
            if (updateResult) {
                return ResultVO.ok("密码修改成功");
            } else {
                return ResultVO.fail("密码修改失败");
            }
            
        } catch (Exception e) {
            log.error("修改密码异常：" + e.getMessage(), e);
            return ResultVO.fail("修改密码失败：" + e.getMessage());
        }
    }

    // 保存用户信息到 Redis
    public void saveUser(String token, UserDetail userInfo) {
        redisTemplate.opsForValue().set(TOKEN_PREFIX + token, JSON.toJSONString(userInfo), 1, TimeUnit.DAYS);  // 设置过期时间为1天
    }

}
